package com.h.forum.controller;

import com.h.forum.common.constant.Constants;
import com.h.forum.common.enums.ResultCode;
import com.h.forum.common.utils.JWTUtil;
import com.h.forum.common.utils.MD5Util;
import com.h.forum.common.utils.StringUtil;
import com.h.forum.common.utils.UUIDUtil;
import com.h.forum.exception.ApplicationException;
import com.h.forum.pojo.model.User;
import com.h.forum.pojo.request.UserLoginRequest;
import com.h.forum.pojo.request.UserModPasswordRequest;
import com.h.forum.pojo.request.UserModifyInfoRequest;
import com.h.forum.pojo.request.UserRegisterRequest;
import com.h.forum.pojo.response.AppResult;
import com.h.forum.pojo.response.UserInfoResponse;
import com.h.forum.pojo.response.UserLoginResponse;
import com.h.forum.services.IUserService;
import io.jsonwebtoken.Jwts;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Slf4j
// 这是一个返回数据的Controller
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource(name = "userServiceImpl")
    private IUserService userService;

    /**
     * 注册用户
     * @param userRegisterRequest
     * @return
     */
    @PostMapping("/register")
    public AppResult register(@Validated @RequestBody UserRegisterRequest userRegisterRequest) {
        log.info("用户注册，userName: " + userRegisterRequest.getUserName());
        // 1、进行判断 密码 和 确认密码 是否相等
        if (!userRegisterRequest.getPassWord()
                .equals(userRegisterRequest.getPassWordRepeat())) {
            // 打印日志
            log.error(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            // 抛出异常，统一处理
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_TWO_PWD_NOT_SAME));
        }

        // 2、密码一致的话，进行处理
        User user = new User();
        user.setUserName(userRegisterRequest.getUserName());
        user.setNickName(userRegisterRequest.getNickName());

        // 3、设置盐值，并且对密码进行加密
        // 先生成唯一盐值
        String salt = UUIDUtil.UUID_32();
        // 使用这个盐值和密码进行加密
        String entryPassword = MD5Util.md5Salt(userRegisterRequest.getPassWord(), salt);

        // 4、往user中存放密码和盐值
        user.setPassWord(entryPassword);
        user.setSalt(salt);

        // 5、存储到数据库中
        userService.createNormalUser(user);

        // 6、返回，进行统一处理
        return AppResult.success();
    }

    /**
     * 登录
     * @param userLoginRequest
     * @return
     */
    @PostMapping("/login")
    public UserLoginResponse login(@Validated @RequestBody UserLoginRequest userLoginRequest) {
        log.info("用户登录，登录的 userName: " + userLoginRequest.getUserName());
        // 1、调用Service层代码，得到用户登录的令牌
        UserLoginResponse response = userService.login(userLoginRequest);

        // 返回这个信息
        return response;
    }

    /**
     * 退出登录
     * @return
     */
    @GetMapping("/logout")
    public AppResult logout() {
        log.info("用户退出登录");
        return AppResult.success("退出成功");
    }

    /**
     * 获取用户信息根据id
     * @param id
     * @return
     */
    @GetMapping("/info")
    // @RequestParam(value = "id", required = false) 表示 id 可以为空
    public AppResult<UserInfoResponse> getInfo(@RequestParam(value = "id", required = false) Long id) {
        // 定义返回的 User 对象
        UserInfoResponse userInfoResponse = null;
        if (id == null) {
            // 说明是当前登录的用户，那么对当前用户进行查询
            Long user_id = JWTUtil.getUserIdFromToken(Constants.JWT);
            userInfoResponse  = userService.selectById(user_id);
        }else {
            // 说明查询的是别人的信息
            userInfoResponse = userService.selectById(id);
        }

        // 判断用户是否为空
        if (userInfoResponse == null) {
            return AppResult.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }

        return AppResult.success(userInfoResponse);
    }

    @PostMapping("/modifyInfo")
    public AppResult modifyInfo(@RequestBody UserModifyInfoRequest request) {
        // 校验参数
        if (StringUtil.isEmpty(request.getEmail())
                && StringUtil.isEmpty(request.getPhoneNum())
                && StringUtil.isEmpty(request.getRemark())
                && StringUtil.isEmpty(request.getUserName())
                && StringUtil.isEmpty(request.getNickName())
                && request.getGender() == null) {
            // 返回错误信息
            return AppResult.fail("请输入要修改的内容");
        }

        // 获取用户Id
        Long userId = JWTUtil.getUserIdFromToken(Constants.JWT);

        // 初始化，构建
        User updateUser = new User();
        updateUser.setId(userId);
        updateUser.setUserName(request.getUserName()); // 用户名
        updateUser.setNickName(request.getNickName()); // 昵称
        updateUser.setGender(request.getGender()); // 性别
        updateUser.setEmail(request.getEmail()); // 邮箱
        updateUser.setPhoneNumb(request.getPhoneNum()); // 电话
        updateUser.setRemark(request.getRemark()); // 个人简介

        // 调用Service进行修改
        userService.modifyInfo(updateUser);

        // 查询修改后的信息，进行返回给前端
        UserInfoResponse userInfo = userService.selectById(userId);

        return AppResult.success(userInfo);
    }


    @PostMapping("/modifyPwd")
    public AppResult modifyPwd(@Validated @RequestBody UserModPasswordRequest request) {
        // 校验新密码和确认密码是否一致
        if (!request.getNewPassword().equals(request.getPasswordRepeat())) {
            return AppResult.fail(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }

        // 调用Service层
        userService.modifyPassword(request);

        return AppResult.success();
    }
}
